package com.joy.ogljoy_01.opengl;

import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.Bitmap;
import android.opengl.GLUtils;
import android.util.Log;

import com.joy.ogljoy_01.R;
import com.joy.ogljoy_01.opengl.proto.Size;
import com.joy.ogljoy_01.opengl.util.BitmapUtil;

public final class Texture2D {

	private static Map<String, Texture2D> __TEXTURES = new HashMap<String, Texture2D>();
	
	public int texId;
	private IntBuffer intBuffer;
	
	/** 纹理大小 */
	public Size rect;
	/** 实际大小 */
	public Size size;

	private int refCount;
	private String name;
	private String key;
	
	private Texture2D(String name) {
		intBuffer = IntBuffer.allocate(1);
		this.name = name;
		linkGL();
	}
	
	/*private Texture2D(Bitmap bmp) {
		intBuffer = IntBuffer.allocate(1);
		linkGL(bmp);
	}*/
	
	public static Texture2D create(String name) {
		String key = name;
		Texture2D texture;
		if(__TEXTURES.containsKey(key)) {
			texture = __TEXTURES.get(key);
		} else {
			texture = new Texture2D(name);
			texture.key = key;
			__TEXTURES.put(key, texture);
		}
		return texture;
	}
	
	/*public static Texture2D create(Bitmap bmp) {
		return new Texture2D(bmp);
	}*/

	public void linkGL() {
		if(name == null) return;
		Bitmap bmp = null;
		if ("IMG.1".equals(name)) {
			bmp = BitmapUtil.makeBitmapFromResourceById(R.drawable.ic_launcher);
//			bmp = BitmapUtil.grayBitmap(bmp);
		} else {
			long sTime = System.currentTimeMillis();
			bmp = BitmapUtil.makeBitmapFromAssets(name);
			long eTime = System.currentTimeMillis();
			System.out.println(name + " : " + (eTime - sTime));
		}
		linkGL(bmp);
	}

	private void linkGL(Bitmap bmp) {
		if(bmp == null) return;
		size = new Size(bmp.getWidth(), bmp.getHeight());
		bmp = BitmapUtil.fixPow2Bitmap(bmp);
		rect = new Size(bmp.getWidth(), bmp.getHeight());
		intBuffer.position(0);
		// 创建纹理
		Graphics.gl.glGenTextures(1, intBuffer);
		texId = intBuffer.get();
		
		bindTexture();
		
		// 生成纹理
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
		
		bmp.recycle();
	}
	public void bindTexture() {
		// 设置需要使用的纹理
		Graphics.gl.glBindTexture(GL10.GL_TEXTURE_2D, texId);
		putTexParameters(Graphics.gl);
	}
	private void putTexParameters(GL10 gl) {
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
		// GL_REPEAT
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
	}

	
	
	public boolean relase() {
		if(--refCount == 0) {
			if(key != null) {
				__TEXTURES.remove(key);
			}
			intBuffer.position(0);
			Graphics.gl.glDeleteTextures(1, intBuffer);
			if(buffer != null) {
				buffer.relase();
			}
			Log.i("HY", "释放：" + key);
			return true;
		}
		return false;
	}
	
	public void ref() {
		this.refCount ++ ;
	}

	private static boolean loaded = false;
	public static void reload() {
		if(!loaded) {
			for (Texture2D tex : __TEXTURES.values()) {
				tex.linkGL();
			}
			loaded = true;
		}
	}
	
	private RenderBuffer buffer;
	public void setRenderBuffer(RenderBuffer buffer) {
		this.buffer = buffer;
	}
	
	public void render() {
		Graphics.draw(texId, buffer);
	}
	
	public void put(float[] vertexs, float[] texcoords) {
		buffer.put(vertexs, texcoords);
	}
	
	public void put(float[] vertexs, FloatBuffer texcoords) {
		buffer.put(vertexs, texcoords);
	}
	
	public void put(FloatBuffer vertexs, FloatBuffer texcoords) {
		buffer.put(vertexs, texcoords);
	}
	
	public void update(int index, float[] vertexs) {
		buffer.update(index, vertexs);
	}
	
	public void update(int index, float[] vertexs, float[] texcoords) {
		buffer.update(index, vertexs, texcoords);
	}
	
}

